<template>
  <div class="api-doc flex-column" :class="apiDesign ? 'design-effect' : ''">
    <div class="api-doc-head flex-row-center flex-row-between">
      <Icon type="logo" class="logo icon-large" />
      <div class="flex-row-center " style="flex-grow:1;overflow: auto;">
        <div class="flex-row-center text-nowrap  click" @click="setDocBase(doc)">
          <span class="doc-name text-nowrap" :title="doc.name">
            {{ doc.name || "匿名文档" }}
          </span>
          <span v-if="doc.desc" class="doc-desc margin-right-5px aux  text-nowrap  " :title="doc.desc"> {{ doc.desc || "" }} </span>
          <Icon type="set" class="icon" />
        </div>
      </div>
      <Icon class="icon icon-large icon-gray click margin-right-05px" type="close" @click="$emit('close')"></Icon>
    </div>
    <div class="doc-nav flex-row-center flex-row-between">
      <div class="doc-info flex-row-center text-nowrap">
        <span class="gray text-nowrap  margin-right-10px ">版本 : {{ doc.version }} </span>
        <span class="warning  text-nowrap margin-right-10px">作者 : {{ doc.author || "匿名" }} </span>
        <span class="info text-nowrap margin-right-10px">时间 : {{ doc.createTime || "无" }}</span>
        <span class="gray text-nowrap margin-right-10px">Base URL : {{ doc.baseURL || "无" }}</span>
      </div>
      <div class="doc-action flex-row-center">
        <span class="btn-text " @click="setApiDesign({})">
          <!-- <Icon slot="step-head" type="add" class="icon" /> -->
          <span> 新增分组 </span>
        </span>
        <span class="btn-text " @click="addApi()">
          <!-- <Icon type="add" class="icon" /> -->
          <span> 新增接口 </span>
        </span>
        <slot name="action"> </slot>
        <span class="btn-text " @click="saveApiDoc()"> <Icon class="icon icon-large" type="save"></Icon>保存 </span>
      </div>
    </div>
    <div class="api-doc-view flex-row ">
      <div class="api-menu flex-column">
        <div class="search flex-row-center">
          <!-- <Icon @click="addApiDoc()" class="icon click" type="add" title="新建接口文档" /> -->
          <Icon class="icon click" type="search" />
          <div class="input">
            <input placeholder="查找api" maxlength="20" v-model.trim="query.keyword" />
          </div>
          <Icon class="icon click" type="close" @click="query.keyword = ''" />
        </div>
        <div class="api-menu-api-list">
          <!-- <div class="text-nowrap1" v-for="(item, i) in doc.list" :key="i">
            <div>{{ item.name }}</div>
          </div> -->
          <template v-for="(group, i) in apiGroup" :key="i">
            <div class="group  flex-row-center" :class="!groupFold[i] ? 'group-open' : 'group-close'">
              <Icon
                @click="groupFold[i] = !groupFold[i]"
                type="arrowDown"
                class="group-trigger click icon-gray icon-mini margin-right-5px"
                :class="!groupFold[i] ? 'group-fold' : ''"
              />
              <span class="blod text-nowrap" @click="groupFold[i] = false" :title="i"> {{ i || "默认分组" }}</span>
              <!-- <span clas="aux">{{ group ? group.length : "" }} </span> -->
            </div>
            <div
              v-for="(item, j) in group"
              :title="item.name"
              :key="j"
              class="api-menu-item  click"
              :class="apiMenuItemCss(item)"
              @click="apiDesign = item"
            >
              <div class="text-nowrap ">{{ item.name || "没有接口名称" }}</div>
            </div>
          </template>
        </div>
      </div>
      <div class="api-design-view ">
        <transition name="anim-api">
          <ApiDesign
            class="abs"
            v-if="apiDesign"
            :key="apiDesign.id"
            @remove="apiDesign = null"
            :apiData="apiDesign"
            :apiDoc="apiDoc"
            :open="true"
          ></ApiDesign>
        </transition>
      </div>
    </div>

    <!-- <transition name="anim-design">
      <div class="abs api-design-box" v-if="apiDesign">
        <ApiDesign
          class="abs"
          type="design"
          @close="setApiDesign(null)"
          v-if="apiDesign"
          @ok="setApi"
          :apiData="apiDesign"
          :apiDoc="doc"
        ></ApiDesign>
      </div>
    </transition> -->
    <transition name="anim-design">
      <ApiDocBase class="abs " v-if="docBase" :apiDoc="doc" @save="saveDocBase" @close="setDocBase()"></ApiDocBase>
    </transition>
  </div>
</template>
<script>
import ApiDesign from "./ApiDesign";
import ApiDocBase from "@/views/ApiDoc/ApiDocBase";
import apiDocSetup from "./apiDoc.setup.js";
import { computed, reactive, provide, watch, inject } from "vue";
let components = { ApiDesign, ApiDocBase };
export default {
  components,
  props: { apiDoc: {} },
  data() {
    return {
      query: {
        keyword: ""
      },
      groupFold: {}, //分组折叠
      docBase: null,
      openApi: null,
      apiDesign: null
    };
  },
  // inject: ["apiDocProvider"],
  setup(props, context) {
    // console.log(props, context);
    let docSetup = apiDocSetup(props, context);
    docSetup.setDoc(props.apiDoc);
    return {
      docSetup
      // docSetup: inject("apiDoc")
      // doc: docSetup.doc
    };
  },
  watch: {
    apiDoc(fresh, old) {
      this.setDoc();
    }
  },

  computed: {
    doc() {
      return this.docSetup.doc || {};
    },
    apiGroup() {
      console.log("[apiGroup]");
      // return this.docSetup.apiGroups();
      let groups = {};
      let list = this.doc.list;

      for (const i in list) {
        let item = list[i];
        item.id = i;
        // item = i;

        let groupName = item.group || "";
        groups[groupName] = groups[groupName] || [];
        if (this.query.keyword && (item.name || "").indexOf(this.query.keyword) == -1) {
          continue;
        }
        if (this.groupFold[groupName]) {
          continue;
        }
        groups[groupName].push(item);
      }
      console.log("groups", groups);
      return list && groups;
    }
  },
  created() {
    console.log("[created]", this.createApiId);
    // window.doc = this;
    // this.setDocContorl();
  },
  methods: {
    apiMenuItemCss(item) {
      let css = {
        ["api-theme-" + item.method]: true,
        active: this.apiDesign && this.apiDesign.id == item.id
      };
      return css;
    },
    createApiId() {
      let idMax = [0, ...Object.values(this.doc.list || {})].reduce((id, i) => {
        return Math.floor(i > 0 && i > id ? i : id);
      });
      return idMax + 1;
    },
    setDocBase(doc) {
      this.docBase = doc;
    },
    saveDocBase(doc) {
      this.save(doc, (result = {}) => {
        result.code == 1 && this.setDocBase();
      });
    },
    setDocContorl() {
      let onbeforeunload = () => {
        this.cache();
      };
      let keydown = (ev) => {
        let ctrlKey = navigator.platform.match("Mac") ? ev.metaKey : ev.ctrlKey;
        let ctrlS = ev.keyCode == 83 && ctrlKey;
        if (ctrlS) {
          ev.preventDefault();
          // console.log(11);
          this.cache();
          this.save();
        }
      };
      window.document.addEventListener("keydown", keydown);
      window.addEventListener("beforeunload", onbeforeunload);
      // this.$once("hook:beforeUnmount", function() {
      //   window.removeEventListener("beforeunload", onbeforeunload);
      //   window.removeEventListener("keydown", keydown);
      // });
    },
    cache(ev) {
      let doc = this.doc;
      doc.updateTime = this.$util.dateFormat();
      doc && this.$api("doc.cache", doc);
    },
    saveApiDoc(doc) {
      this.save(this.doc, (result = {}) => {
        this.$emit("set-design", null);
      });
    },
    save(doc, callback) {
      console.log("[doc.save]", doc);
      if (!doc) return;
      if (!doc.name) {
        this.setDocBase(doc);
        return window.alert("输入文档名称");
      }
      let param = JSON.parse(JSON.stringify(doc));
      let time = this.$util.dateFormat();
      param.createTime = param.createTime || time;
      param.updateTime = time;

      this.$api("doc.save", param).then((result = {}) => {
        console.log("[doc.save]", result);
        callback && callback(result);
        if (result.code != 1) {
          window.alert(result.message);
        } else {
          this.doc = result.data;
        }
      });
    },
    setCloseGroup(group) {
      // console.log(group);
      let close = !this.groupFold[group];
      this.$set(this.groupFold, group, close);
    },
    setOpenApi(api) {
      if (api) {
        let openApi = api.group + api.name;
        this.openApi = this.openApi == openApi ? null : openApi;
      }
    },
    setDoc() {
      this.doc = Object.assign({}, this.formBase, this.apiDoc);
      console.log("[setDoc]", this.doc, this.apiDoc);
      this.setApiDesign();
      this.setDocBase(this.apiDoc && !this.doc.name ? this.doc : null);
    },
    setApiDesign(api) {
      this.apiDesign = api;
    },
    todoList() {
      let list = [];
      for (const i in this.todos) {
        list.push(this.todos[i]);
      }
      return list;
    },
    setApi(api) {
      console.log("[setApi]", api, this.apiDesign);
      if (!api || !this.apiDesign) {
        return;
      }
      if (!this.doc.api) {
        this.$set(this.doc, "api", []);
      }
      let list = (this.doc || {}).api || [];
      let indexOld = list.findIndex((item) => {
        let key = item.group + item.name;
        let key1 = this.apiDesign.group + this.apiDesign.name;
        return key == key1;
      });
      let indexFresh = list.findIndex((item) => {
        let key = item.group + item.name;
        let key1 = api.group + api.name;
        return key == key1;
      });
      console.log("[setApi]", indexFresh, indexOld);
      if (indexFresh != -1 && (indexOld == -1 || indexOld !== indexFresh)) {
        return window.alert(`api名称重复 \n分组 : ${api.group} \napi名称 : ${api.name} `);
      }
      if (indexOld == -1) {
        this.doc.api.unshift(api);
      } else {
        this.doc.api[indexOld] = api;
      }
      this.setApiDesign();
    },
    removeApi(api = {}) {
      console.log(api);
      let index = (this.doc.list || []).findIndex((item) => {
        return item.group + item.name === api.group + api.name;
      });
      if (!(index >= 0)) {
        return;
      }
      var msg = "确认删除:\n" + api.group + " - " + api.name + "";
      if (window.confirm(msg)) {
        try {
          this.docSetup.removeApi(index, 1);
        } catch (error) {
          console.error("[removeApi]", error);
        }
      }
    },
    addApi(group = "", name = "") {
      // this.docSetup.doc.list.unshift({});
      // this.list.unshift(this.docSetup.apiBase());
      this.apiDesign = this.docSetup.addApi();
    }
  }
};
</script>
<style>
.api-doc {
  /* background-color: #0001; */
  z-index: 2;
  max-width: 1200px;
  top: 40px;
  bottom: 40px;
  /* transition: 0.3s, filter 0.2s; */
  /* backdrop-filter: blur(5px); */
  background-color: #fffe;
  border-radius: 10px;
  background: linear-gradient(145deg, #e2dddd 0%, #d3e1e9 40%, #fcfcfa 100%);
  border: 1px solid #5552;
  border-radius: 5px;
  box-shadow: 0 0 50px #ddd, 5px 5px 15px #ddd;
  margin: auto;
}

.api-doc-view {
  flex-grow: 1;
  overflow: auto;
  margin-bottom: 2px;
}
.api-design-box {
  z-index: 10;
  top: 80px;
  margin: 10px;
  box-shadow: 5px 5px 15px #aaa;
  /* padding: 10px; */
  transform-origin: 50% 0%;
  border-radius: 5px;
  background: linear-gradient(145deg, #e2dddd 0%, #d3e1e9 40%, #fcfcfa 100%);
  /* backdrop-filter: blur(15px); */
  /* box-shadow: 5px -5px 15px #ddd; */
}
.api-design-view {
  position: relative;
  flex-grow: 1;
  overflow: hidden;
}
.design-effect .api-doc-view {
  /* filter: blur(7px);
  transition: 0.3s, filter 0.7s; */
  /* transform: scale(0.4); */
  /* opacity: 0.1; */
}
/* .design-effect {
  transform: scale(0.5);
  transition: transform 0.3s;
}
.design-effect .api-design-box {
  transform: scale(2);
} */

.step-group .icon-gray {
  transition: 0.3s;
  fill: #999;
}
.group-open {
  /* transform: rotate(0deg); */
  /* fill: #000 !important; */
}
.group-close {
  /* transform: rotate(-45deg); */
  fill: rgb(23, 126, 211) !important;
}

.group-trigger {
  transition: 0.2s;
  transform: rotate(-90deg);
}
.group-fold {
  transform: rotate(0deg);
}
.btn-add-doc {
  margin-left: -27px;
}

.btn-add-doc .icon {
  margin-right: 15px !important;
}
.step-group .step-head {
  margin-top: 2px;
}
.step-api .step-head {
  margin-top: 8px;
}
.api-doc-head {
  position: relative;
  transition: filter 0.2s;
  padding: 10px;
  border-bottom: 1px dashed #cccc;
}
.doc-nav {
  position: relative;
  padding: 5px 0;
  background-color: #f5f5f522;
  border-bottom: 1px solid #ddd;
}
.dashed {
  flex-grow: 1;
  border-bottom: 1px dashed #dddd;
}
.api-doc-base {
  /* padding-top: 5px; */
  padding-bottom: 0;
  background-color: var(--color-back-head);
  /* padding-bottom: 5px; */
}
.doc-name {
  font-size: 1.2rem;
  font-weight: bold;
  padding-left: 10px;
}
.doc-desc {
  font-size: 0.9rem;
  padding-left: 10px;
  overflow: hidden;
  /*     padding-left: 10px;
  color: var(--color-gray); */
}
.doc-info {
  font-size: 0.7rem;
  color: var(--color-gray);
  padding: 2px 0;
  padding-left: 10px;
  overflow: auto;
}
.doc-action {
  flex-shrink: 0;
}
.doc-info .btn-text {
  transform: translateY(-5px);
}
.api-list {
  position: relative;
  flex-grow: 1;
  overflow: auto;
  padding-bottom: 5px;
}

.api-doc-base .step-head::before {
  top: -25px;
}
.api-doc-base .logo {
  margin-top: 2px;
}

.api-menu {
  width: 220px;
  flex-shrink: 0;
  border-right: 1px solid #ccc5;
}
.api-menu .search {
  margin: 2px 5px;
  flex-shrink: 0;
  /* border: 1px solid #cccc; */
}
.api-menu-api-list {
  border-top: 1px solid #ccc5;
  overflow: auto;
}
.api-menu-api-list .group {
  padding-left: 5px;
  margin-top: 5px;
  /* color: rgb(226, 128, 36); */
}
.api-menu-item {
  padding: 3px;
  padding-left: 15px;
  position: relative;
}
.api-menu-item.active {
  filter: grayscale(0.5);
  opacity: 0.8;
  background-color: #ecf3f33a;
  text-decoration: underline;
  /* font-weight: bold; */
  /* background-color: #ecf3f33a;
  color: rgb(24, 134, 238); */
  /* box-shadow: 0 0 3px #ecf3f39a; */
  /* background: linear-gradient(-145deg, #e2dddd 0%, #d5e3ec 40%, #fcfcfa 100%); */
}
/* .api-menu-item.active::before {
  content: "";
  position: absolute;
  top: -2px;
  left: 0px;
  right: 0px;
  bottom: -2px;
  background-color: #ecf3f39a;
  box-shadow: 0 0 2px #ecf3f3ce;
  z-index: -1;
} */
.list-item {
  margin-bottom: 15px;
}
</style>
